/*
 * @Author: 晴鸢. 3013433857@qq.com
 * @Date: 2025-11-05 08:11:20
 * @LastEditors: 晴鸢. 3013433857@qq.com
 * @LastEditTime: 2025-11-05 19:40:52
 * @FilePath: /Learn/Webself/TcpServer.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
#include<string>
#include<iostream>
#include<functional>
#include<signal.h>
#include"protohol.hpp"
#include"Log.hpp"
#include"socket.hpp"
using fun_t=std::function<std::string(std::string&)>;
class TcpServer
{
public:
    TcpServer(const uint16_t& port,fun_t callback) 
    :_port(port),_callback(callback)
    {}

    bool Init()
    {
        _listenfd.Socket();
        _listenfd.Bind(_port);
        _listenfd.Listen();
        lg(Info,"init server... done");
        return true;
    }

    bool start()
    {
        signal(SIGPIPE,SIG_IGN);
        signal(SIGCHLD,SIG_IGN);
        while(true)
        {
            std::string clientip;
            uint16_t clientport;
            int sockfd=_listenfd.Accept(clientip,clientport);
            if(sockfd<0) continue;
            lg(Info,"Server get a new link,ip:%s,port:%d",clientip.c_str(),clientport);
            if(fork()==0)
            {
                _listenfd.Close();
                std::string stream_buffer;
                while(true)
                {
                    char buffer[128];
                    int n=read(sockfd,buffer,sizeof(buffer));
                    if(n>0)
                    {
                        buffer[n]='\0';
                        stream_buffer+=buffer;
                        lg(Debug, "debug:\n%s", stream_buffer.c_str());
                        while(true)
                        {
                            std::string str=_callback(stream_buffer);
                            if(str.empty()) break;
                            lg(Info,"Response:\n%s",str.c_str());
                            lg(Info,"stream:\n%s",stream_buffer.c_str());
                            
                            write(sockfd,str.c_str(),str.size());
                        }
                    }
                    else if(n==0) break;
                    else break;
                }
                exit(0);
            }
            close(sockfd);
        }
    }

    ~TcpServer()
    {}
private:
    Sock _listenfd;
    uint16_t _port;
    fun_t _callback;
};